﻿using Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Linguist.Flat
{
    /// <summary>
    /// Represents a transition in a sentence HMM. Each transition is described by the next state and the associated acoustic
    /// and language probability for the transition.
    /// 
    /// All probabilities are in the LogMath log domain
    /// </summary>
    public class SentenceHMMStateArc : ISearchStateArc
    {
        private SentenceHMMState nextState;
        private float logLanguageProbability;
        private float logInsertionProbability;
        private int _hashCode;


        /**
        /// Creates a SentenceHMMStateArc
         *
        /// @param nextState               the next state
        /// @param logLanguageProbability  the log language probability
        /// @param logInsertionProbability the log insertion probability
         */
        public SentenceHMMStateArc(SentenceHMMState nextState,
                                   float logLanguageProbability,
                                   float logInsertionProbability) 
        {
            this.nextState = nextState;
            this.logLanguageProbability = logLanguageProbability;
            this.logInsertionProbability = logInsertionProbability;

            _hashCode = 111 + nextState.GetHashCode() +
                    17* Convert.ToInt32(logLanguageProbability) +
                    23* Convert.ToInt32(logInsertionProbability);

        }


        /**
        /// Determines if the given object is equal to this object
         *
        /// @param o the object to compare to
        /// @return <code>true</code> if the objects are equal
         */
        override  public Boolean Equals(Object o) 
        {
            if (this == o) 
            {
                return true;
            } 
            else if (o is SentenceHMMStateArc) 
            {
                SentenceHMMStateArc other = (SentenceHMMStateArc) o;
                return nextState == other.nextState &&
                        logLanguageProbability == other.logLanguageProbability &&
                        logInsertionProbability == other.logInsertionProbability;

            } 
            else 
            {
                return false;
            }
        }


        /**
        /// Returns a hashCode for this object
         *
        /// @return the hashCode
         */
        public int hashCode() 
        {
            return _hashCode;
        }


        /**
        /// Retrieves the next state
         *
        /// @return the next state
         */
        public ISearchState getState() 
        {
            return nextState;
        }


        /**
        /// For backwards compatibility
        /// <p/>
        /// Returns the next state as a SentenceHMSMtate
         *
        /// @return the next state
         */
        public SentenceHMMState getNextState() 
        {
            return (SentenceHMMState) getState();
        }


        /**
        /// Retrieves the language transition probability for this transition
         *
        /// @return the language  transition probability in the logmath log domain
         */
        public float getLanguageProbability() 
        {
            return logLanguageProbability;
        }


        /**
        /// Retrieves the insertion probability for this transition
         *
        /// @return the insertion probability  in the logmath log domain
         */
        public float getInsertionProbability() 
        {
            return logInsertionProbability;
        }


        /**
        /// Gets the composite probability of entering this state
         *
        /// @return the log probability
         */
        public float getProbability() 
        {
            return logLanguageProbability + logInsertionProbability;
        }

    }
}
